<template>
    <!-- 热力图组件不需要模板，直接操作地图API -->
    <div class="abcdfalse" v-if="false"></div>
</template>

<script setup>
import { ref, watch, onUnmounted } from 'vue'
import { amapPoiData } from './amapPoiData.js'

// Props
const props = defineProps({
    map: {
        type: Object,
        required: true
    },
    enabled: {
        type: Boolean,
        default: false
    },
    visible: {
        type: Boolean,
        default: true
    }
})

// Emits
const emit = defineEmits(['heatmap-created', 'heatmap-removed'])

// 响应式数据
const heatmapLayer = ref(null)

// 热力图配置常量
const ZOOM_THRESHOLD = 14 // 缩放级别阈值
const MAX_RADIUS = 40 // 最大半径
const MIN_RADIUS = 15 // 最小半径
const TRANSITION_ZONE = 2 // 过渡区间（缩放级别）

// 当前地图缩放级别
const currentZoom = ref(15)

// 坐标转换函数
const PI = Math.PI
const a = 6378245.0
const ee = 0.00669342162296594323

const outOfChina = (lng, lat) => {
    return (lng < 72.004 || lng > 137.8347) || (lat < 0.8293 || lat > 55.8271)
}

const transformLat = (lng, lat) => {
    let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng))
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
    ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0
    ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0
    return ret
}

const transformLng = (lng, lat) => {
    let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng))
    ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0
    ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0
    ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0
    return ret
}

const wgs84ToGcj02 = (lng, lat) => {
    if (outOfChina(lng, lat)) {
        return [lng, lat]
    }

    let dlat = transformLat(lng - 105.0, lat - 35.0)
    let dlng = transformLng(lng - 105.0, lat - 35.0)

    const radlat = lat / 180.0 * PI
    let magic = Math.sin(radlat)
    magic = 1 - ee * magic * magic
    const sqrtmagic = Math.sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI)
    dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI)

    const mglat = lat + dlat
    const mglng = lng + dlng

    return [mglng, mglat]
}

const convertPoiCoordinates = (coordinates) => {
    const [convertedLng, convertedLat] = wgs84ToGcj02(coordinates.lng, coordinates.lat)
    return {
        lng: convertedLng,
        lat: convertedLat
    }
}

// 根据缩放级别计算热力图半径
const calculateRadius = (zoom) => {
    // 使用平滑的分段线性插值函数
    if (zoom >= ZOOM_THRESHOLD + TRANSITION_ZONE) {
        // 高缩放级别：使用最大半径
        return MAX_RADIUS
    } else if (zoom >= ZOOM_THRESHOLD) {
        // 过渡区间：线性插值，实现平滑过渡
        const progress = (zoom - ZOOM_THRESHOLD) / TRANSITION_ZONE
        const smoothProgress = progress * progress * (3 - 2 * progress) // 使用平滑步函数
        return MIN_RADIUS + (MAX_RADIUS - MIN_RADIUS) * smoothProgress
    } else {
        // 低缩放级别：使用对数函数实现更平滑的缩放
        const minZoom = 10 // 最小支持的缩放级别
        const normalizedZoom = Math.max(zoom - minZoom, 0) / (ZOOM_THRESHOLD - minZoom)
        const smoothZoom = Math.pow(normalizedZoom, 0.7) // 使用幂函数平滑曲线
        return Math.max(MIN_RADIUS * smoothZoom, 6) // 最小半径为6
    }
}

// 更新热力图半径
const updateHeatmapRadius = (newRadius) => {
    if (heatmapLayer.value) {
        try {
            // 重新配置热力图参数
            heatmapLayer.value.setOptions({
                radius: newRadius,
                opacity: [0.3, 0.9],
                gradient: {
                    0.1: '#0080ff',
                    0.3: '#00bfff',
                    0.5: '#00ff80',
                    0.6: '#80ff00',
                    0.7: '#ffff00',
                    0.8: '#ff8000',
                    0.9: '#ff4000',
                    1.0: '#ff0000'
                },
                zooms: [10, 18],
                blur: 0.8
            })
            console.log(`热力图半径已更新为: ${newRadius}`)
        } catch (error) {
            console.error('更新热力图半径失败:', error)
        }
    }
}

// 监听地图缩放变化
const setupZoomListener = () => {
    if (!props.map) return
    
    // 获取当前缩放级别
    currentZoom.value = props.map.getZoom()
    
    // 监听缩放变化事件
    props.map.on('zoomend', () => {
        const newZoom = props.map.getZoom()
        if (newZoom !== currentZoom.value) {
            currentZoom.value = newZoom
            const newRadius = calculateRadius(newZoom)
            updateHeatmapRadius(newRadius)
            // console.log(`地图缩放级别变化: ${newZoom}, 新半径: ${newRadius}`)
        }
    })
    
    // 也监听缩放过程中的变化（实时更新）
    props.map.on('zoomchange', () => {
        const newZoom = props.map.getZoom()
        if (Math.abs(newZoom - currentZoom.value) > 0.4) { // 降低阈值，让过渡更平滑
            currentZoom.value = newZoom
            const newRadius = calculateRadius(newZoom)
            updateHeatmapRadius(newRadius)
        }
    })
}

// 移除地图缩放监听
const removeZoomListener = () => {
    if (props.map) {
        props.map.off('zoomend')
        props.map.off('zoomchange')
    }
}

// 创建热力图
const createHeatmap = () => {
    if (!props.map || !window.AMap) {
        console.warn('地图对象或高德地图API未准备就绪')
        return
    }

    // 如果已经有热力图，先移除
    if (heatmapLayer.value) {
        console.log('检测到现有热力图，先移除')
        removeHeatmap()
        // 等待移除完成
        return setTimeout(() => createHeatmap(), 100)
    }

    // 获取摄像头POI数据
    const monitorPois = amapPoiData.filter(poi => poi.type === 'monitor')

    if (monitorPois.length === 0) {
        console.warn('没有找到摄像头POI数据')
        return
    }

    console.log('开始创建热力图...')

    // 转换摄像头POI数据为热力图数据格式
    const heatmapData = monitorPois.map(poi => {
        const convertedCoords = convertPoiCoordinates(poi.coordinates)
        // 根据POI的实际数据生成热力值
        const baseHeat = poi.data?.heatValue || 30
        const randomFactor = Math.floor(Math.random() * 30) + 10 // 10-40的随机值
        const alertBonus = poi.isAlert ? 20 : 0 // 异常POI增加热力值

        return {
            lng: convertedCoords.lng,
            lat: convertedCoords.lat,
            count: Math.min(baseHeat + randomFactor + alertBonus, 100) // 限制最大值为100
        }
    })

    try {
        // 创建热力图图层
        props.map.plugin(['AMap.HeatMap'], () => {
            // 再次检查是否已经有热力图，避免重复创建
            if (heatmapLayer.value) {
                console.log('热力图已存在，取消重复创建')
                return
            }

            // 获取当前缩放级别并计算初始半径
            currentZoom.value = props.map.getZoom()
            const initialRadius = calculateRadius(currentZoom.value)

            heatmapLayer.value = new AMap.HeatMap(props.map, {
                radius: initialRadius, // 使用动态计算的半径
                opacity: [0.3, 0.9], // 透明度区间 - 提高最小和最大透明度
                gradient: { // 热力图渐变色配置
                    0.1: '#0080ff', // 蓝色 - 低热力值
                    0.3: '#00bfff', // 天蓝色
                    0.5: '#00ff80', // 绿色 - 中等热力值
                    0.6: '#80ff00', // 黄绿色
                    0.7: '#ffff00', // 黄色
                    0.8: '#ff8000', // 橙色
                    0.9: '#ff4000', // 深橙色
                    1.0: '#ff0000'  // 红色 - 高热力值
                },
                zooms: [10, 18], // 热力图显示的缩放级别范围
                blur: 0.8 // 模糊程度，让热力点更加柔和
            })

            // 设置热力图数据
            heatmapLayer.value.setDataSet({
                data: heatmapData,
                max: 100 // 最大权重值
            })

            // 设置缩放监听
            setupZoomListener()

            console.log(`热力图创建成功，数据点数量: ${heatmapData.length}, 初始半径: ${initialRadius}, 当前缩放级别: ${currentZoom.value}`)
            emit('heatmap-created', {
                dataPoints: heatmapData.length,
                maxValue: Math.max(...heatmapData.map(d => d.count)),
                initialRadius: initialRadius,
                zoomLevel: currentZoom.value
            })
        })
    } catch (error) {
        console.error('创建热力图失败:', error)
    }
}

// 移除热力图
const removeHeatmap = () => {
    if (heatmapLayer.value && props.map) {
        try {
            console.log('正在移除热力图...')
            
            // 移除缩放监听
            removeZoomListener()
            
            // 先隐藏热力图
            heatmapLayer.value.hide()
            // 然后从地图上移除
            props.map.remove(heatmapLayer.value)
            // 销毁热力图对象
            if (heatmapLayer.value.destroy && typeof heatmapLayer.value.destroy === 'function') {
                heatmapLayer.value.destroy()
            }
            heatmapLayer.value = null
            console.log('热力图已成功移除')
            emit('heatmap-removed')
        } catch (error) {
            console.error('移除热力图失败:', error)
            // 强制重置
            heatmapLayer.value = null
        }
    } else if (heatmapLayer.value) {
        // 如果地图对象不存在，直接重置
        console.log('地图对象不存在，直接重置热力图引用')
        removeZoomListener()
        heatmapLayer.value = null
        emit('heatmap-removed')
    }
}

// 更新热力图可见性（暂时保留，但主要通过创建/移除来控制）
const updateVisibility = () => {
    if (!heatmapLayer.value) return

    if (props.visible && props.enabled) {
        heatmapLayer.value.show()
    } else {
        heatmapLayer.value.hide()
    }
}

// 监听props变化
watch(() => props.enabled, (newEnabled) => {
    // console.log('热力图enabled状态变化:', newEnabled)

    if (newEnabled && props.visible) {
        // 开启热力图
        createHeatmap()
    } else {
        // 关闭热力图：直接移除
        removeHeatmap()
    }
}, { immediate: true })

watch(() => props.visible, (newVisible) => {
    if (props.enabled) {
        if (newVisible) {
            // 只有当前没有热力图时才创建，避免重复创建
            if (!heatmapLayer.value) {
                createHeatmap()
            }
        } else {
            // 不可见时移除热力图
            removeHeatmap()
        }
    }
})

watch(() => props.map, (newMap) => {
    if (newMap && props.enabled && props.visible) {
        // 地图对象变化时重新创建热力图
        setTimeout(() => {
            createHeatmap()
        }, 100)
    }
})

// 组件卸载时清理
onUnmounted(() => {
    removeHeatmap()
})

// 暴露方法给父组件
defineExpose({
    createHeatmap,
    removeHeatmap,
    updateVisibility
})
</script>

<style scoped>
/* 热力图组件不需要样式 */
</style>
